<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Processes
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora166.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora168.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Processes</H2><A NAME="sec-proc"></A>
<A NAME="@concepts339"></A>
Unix associates a <EM>process</EM> with each execution of a program.
In [<A HREF="book-ora214.html#Mevel"><CITE>CDM98</CITE></A>] Card, Dumas and M�vel describe the difference between
a program and a process:
``a program itself is not a process: a program is a passive entity
(an executable file on a disc), while a process is an active entity
with a counter specifying the next instruction to execute and a set
of associated resources.''<BR>
<BR>
Unix is a multi-task operating system: many processes
may be executed at the same time. It is preemptive, which means
that the execution of processes is entrusted to a particular
process. A process is therefore not totally master of its resources.
Especially a process can not determine the time of its execution.
A process has to be created.<BR>
<BR>
Each process has his own private memory space. Processes can
communicate via files or communication channels. Thus the distributed memory
model of parallelism is simulated on a single machine.<BR>
<BR>
The system gives each process a unique identifier: the PID
(Process IDentifier). Under Unix each process, except
the initial process, is created by another process, which is called
its parent.<BR>
<BR>
The set of all active processes can be listed by the Unix
command <TT>ps</TT><A NAME="text42" HREF="book-ora172.html#note42"><SUP><FONT SIZE=2>3</FONT></SUP></A>:
<PRE>
$ ps -f
PID    PPID    CMD
1767   1763   csh
2797   1767   ps -f
</PRE>The use of the option <TT>-f</TT> adds for each active process its
identifier (<TT>PID</TT>), that of its parent (<TT>PPID</TT>) and the
name of the started program (<TT>CMD</TT>). Here we have two
processes, the command line interpreter <TT>csh</TT> and the command
<TT>ps</TT> itself. It can be seen that <TT>ps</TT> has been started from
the command line interpreter <TT>csh</TT>. The parent of its process
is the process associated with the execution of <TT>csh</TT>.<BR>
<BR>
<A NAME="toc246"></A>
<H3> Executing a Program</H3>
<A NAME="sec-prog-env"></A>
<H4> Execution Context</H4>
Three values are associated with an executing program, which is started from the
command line:
<OL type=1>
<LI>
 The command line used to start it. It is contained in
the value <TT>Sys.argv</TT>.

<LI> The environment variables of the command line interpreter.
These can be accessed by the command <TT>Sys.getenv</TT>.

<LI> An execution status until the program is terminated.
</OL>
<H5> Command line.</H5>
The command line allows you to read arguments or options of a program call.
The behavior of the program may depend from these values.
Here is a small example. We write the following program
into the file <TT>argv_ex.ml</TT>:<BR>
<BR>


<PRE><BR><B>if</B><CODE> </CODE>Array.length<CODE> </CODE>Sys.argv<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE><B>then</B><BR><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"Hello world\n"</CODE><BR><B>else</B><CODE> </CODE><B>if</B><CODE> </CODE>Array.length<CODE> </CODE>Sys.argv<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE><B>then</B><BR><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"Hello %s\n"</CODE><CODE> </CODE>Sys.argv<CODE>.</CODE><TT>(</TT><CODE>1</CODE><TT>)</TT><BR><B>else</B><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"%s : too many arguments\n"</CODE><CODE> </CODE>Sys.argv<CODE>.</CODE><TT>(</TT><CODE>0</CODE><TT>)</TT><BR>

</PRE>
<BR>
<BR>
We compile it:
<PRE>
$ ocamlc -o argv_ex argv_ex.ml
</PRE>And we execute it:
<PRE>
$ argv_ex
Hello world
$ argv_ex reader
Hello reader
$ argv_ex dear reader
./argv_ex : too many arguments
</PRE>
<H5> Environment variables.</H5>
Environment variables may contain values necessary for execution.
The number and the names of these variables depend on the
operating system and on the user configuration. The values of these
variables can be accessed by the function <TT>getenv</TT>,
which takes as argument the name of a variable in form of a
character string:


<PRE><BR>#<CODE> </CODE>Sys.getenv<CODE> </CODE><CODE>"HOSTNAME"</CODE>;;<BR><CODE>-</CODE><CODE> </CODE><CODE>:</CODE><CODE> </CODE>string<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"zinc.pps.jussieu.fr"</CODE><BR>

</PRE>
<BR>
<BR>

<H4> Execution Status</H4>
The return value of a program is generally a fixed integer,
indicating if the program did terminate with an error or not.
The exact values may differ from one operating system to another.
The programer can always explicitly stop his program and return
the execution status value with the function call:


<PRE><BR># Pervasives.exit<CODE> </CODE>;;<BR><CODE>- : int -&gt; 'a = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="toc247"></A>
<H3> Process Creation</H3>
<A NAME="@concepts340"></A>
A program is started by another process, which is called
the current process. The executed program becomes a new process.
There are three different relations between the two processes:
<UL>
<LI>
 The two processes are independent from each other
and can be executed concurrently.

<LI> The parent process is waiting for the child process to terminate.

<LI> The created process replaces the parent process, which terminates.
</UL>
It is also possible to duplicate the current process to obtain two instances.
The two instances of the process do not differ but in their PID.
This is the famous <TT>fork</TT> which we will describe later. <BR>
<BR>

<H4> Independent Processes</H4>
<A NAME="sec-create-process"></A>
The <TT>Unix</TT> module offers a portable function to create a process.
<A NAME="@fonctions423"></A>


<PRE><BR># Unix.create_process<CODE> </CODE>;;<BR><CODE>- : string -&gt;</CODE><BR><CODE>    string array -&gt;</CODE><BR><CODE>    Unix.file_descr -&gt; Unix.file_descr -&gt; Unix.file_descr -&gt; int</CODE><BR><CODE>= &lt;fun&gt;</CODE><BR>

</PRE>

The first argument is the name of the program (it may be a path).
The second is the array of arguments for the program. The last three
arguments are the descriptors indicating the standard input,
standard output and standard error output of the process. The
return value is the PID of the created process.<BR>
<BR>
There also exists a variant of this function which allows you to indicate
the values of environment variables:


<PRE><BR># Unix.create_process_env<CODE> </CODE>;;<BR><CODE>- : string -&gt;</CODE><BR><CODE>    string array -&gt;</CODE><BR><CODE>    string array -&gt;</CODE><BR><CODE>    Unix.file_descr -&gt; Unix.file_descr -&gt; Unix.file_descr -&gt; int</CODE><BR><CODE>= &lt;fun&gt;</CODE><BR>

</PRE>

These two functions can be used under Unix and Windows. <BR>
<BR>
GGH<BR>
<BR>

<H4> Process Stacks</H4>
It is not always useful for a created process to be of concurrent nature.
The parent process may have to wait for the created process to
terminate. The two following functions take as argument the
name of a command and execute it.


<PRE><BR># Sys.command;;<BR><CODE>- : string -&gt; int = &lt;fun&gt;</CODE><BR># Unix.system;;<BR><CODE>- : string -&gt; Unix.process_status = &lt;fun&gt;</CODE><BR>

</PRE>

They differ in the type of the return code. The type
<I>process_status</I> is explained in more detail on page
<A HREF="book-ora167.html#type-process-status">??</A>.
During the execution of the command the parent process is blocked.<BR>
<BR>

<H4> Replacement of Current Processes</H4>
The replacement of current processes by freshly created processes
allows you to limit the number of concurrently executed processes.
The four following functions allow this:


<PRE><BR># Unix.execv<CODE> </CODE>;;<BR><CODE>- : string -&gt; string array -&gt; unit = &lt;fun&gt;</CODE><BR># Unix.execve<CODE> </CODE>;;<BR><CODE>- : string -&gt; string array -&gt; string array -&gt; unit = &lt;fun&gt;</CODE><BR># Unix.execvp<CODE> </CODE>;;<BR><CODE>- : string -&gt; string array -&gt; unit = &lt;fun&gt;</CODE><BR># Unix.execvpe<CODE> </CODE>;;<BR><CODE>- : string -&gt; string array -&gt; string array -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

Their first argument is the name of the program. Using
<TT>execvp</TT> or <TT>execvpe</TT>, this name may indicate a path
in the file system. The second argument contains the program arguments.
The last argument of the functions <TT>execve</TT> and
<TT>execvpe</TT> additionally allows you to indicate the values of
system variables.<BR>
<BR>
<A NAME="toc248"></A>
<H3> Creation of Processes by Duplication</H3>
<A NAME="sec-fork"></A>
The original system call to create processes under Unix is:


<PRE><BR># Unix.fork<CODE> </CODE>;;<BR><CODE>- : unit -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
The function <TT>fork</TT> starts a new process, not a new program.
Its effect is to <EM>duplicate</EM> the calling process. The code of
the new process is the same as that of its parent. Under Unix
the same code can be shared by several processes, each process possessing
its own execution context. Therefore we speak about
reentrant code.<BR>
<BR>
Let's look at the following small program (we use the function 
<TT>getpid</TT> which returns the PID of the process associated
with the execution):<BR>

<PRE>
Printf.printf<CODE> </CODE><CODE>"before fork : %d\n"</CODE><CODE> </CODE><TT>(</TT>Unix.getpid<CODE> </CODE>()<TT>)</TT><CODE> </CODE><CODE> </CODE>;;<BR>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR>Unix.fork<CODE> </CODE>()<CODE> </CODE>;;<BR>Printf.printf<CODE> </CODE><CODE>"after fork : %d\n"</CODE><CODE> </CODE><TT>(</TT>Unix.getpid<CODE> </CODE>()<TT>)</TT><CODE> </CODE><CODE> </CODE>;;<BR>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
We obtain the following output:<BR>

<PRE>
<CODE>before fork : 10529</CODE><BR><CODE>after fork : 10529</CODE><BR><CODE>after fork : 10530</CODE><BR>

</PRE>
<BR>
<BR>
After the execution of <TT>fork</TT>, two processes execute the code.
This leads to the output of two PID's ``<TT>after</TT>'' the
<TT>fork</TT>. We note that
one process has kept the PID of the beginning (the parent).
The other one has a new PID (the child), which corresponds to the
return value of the <TT>fork</TT> call. For the parent process
the return value of <TT>fork</TT> is the PID of the child, while for
the child, it is <EM>0</EM>.<BR>
<BR>
It is this difference in the return value of <TT>fork</TT> which
allows <EM>in one program source</EM> to decide which code shall be
executed by the child and which by the parent:<BR>

<PRE>
Printf.printf<CODE> </CODE><CODE>"before fork : %d\n"</CODE><CODE> </CODE><TT>(</TT>Unix.getpid<CODE> </CODE>()<TT>)</TT><CODE> </CODE><CODE> </CODE>;;<BR>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR><B>let</B><CODE> </CODE>pid<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE>;;<BR><B>if</B><CODE> </CODE>pid<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>then</B><CODE> </CODE><CODE> </CODE><CODE>(* -- Code of the child *)</CODE><BR><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"I am  the child: %d\n"</CODE><CODE> </CODE><TT>(</TT>Unix.getpid<CODE> </CODE>()<TT>)</TT><CODE> </CODE><CODE> </CODE><BR><B>else</B><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* -- Code of the father *)</CODE><BR><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"I am the father: %d of child: %d\n"</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Unix.getpid<CODE> </CODE>()<TT>)</TT><CODE> </CODE>pid<CODE> </CODE>;;<BR>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
Here is the trace of the execution of this program:<BR>

<PRE>
<CODE>before fork : 10539</CODE><BR><CODE>I am the father: 10539 of child: 10540</CODE><BR><CODE>I am  the child: 10540</CODE><BR>

</PRE>
<BR>
<BR>
It is also possible to use the return value for matching:<BR>

<PRE>
<B>match</B><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"I am the child: %d\n"</CODE><CODE> </CODE><TT>(</TT>Unix.getpid<CODE> </CODE>()<TT>)</TT><BR><CODE>|</CODE><CODE> </CODE>pid<CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"I am the father: %d of child: %d\n"</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Unix.getpid<CODE> </CODE>()<TT>)</TT><CODE> </CODE>pid<CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
The fertility of a process may be very big. Therefore the
number of descendents of a process is limited by the
configuration of the operating system. The following example
creates two generations of processes with grandparent, parents,
uncles and cousins.<BR>

<PRE>
<B>let</B><CODE> </CODE>pid0<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Unix.getpid<CODE> </CODE>();;<BR><B>let</B><CODE> </CODE>print_generation1<CODE> </CODE>pid<CODE> </CODE>ppid<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"I am %d, son of %d\n"</CODE><CODE> </CODE>pid<CODE> </CODE>ppid;<BR><CODE> </CODE><CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR><BR><B>let</B><CODE> </CODE>print_generation2<CODE> </CODE>pid<CODE> </CODE>ppid<CODE> </CODE>pppid<CODE> </CODE><CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"I am %d, son of %d, grandson of %d\n"</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>pid<CODE> </CODE>ppid<CODE> </CODE>pppid;<BR><CODE> </CODE><CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR><BR><B>match</B><CODE> </CODE>Unix.fork()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>let</B><CODE> </CODE>pid01<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Unix.getpid<CODE> </CODE>()<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><TT>(</TT><CODE> </CODE><B>match</B><CODE> </CODE>Unix.fork()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_generation2<CODE> </CODE><TT>(</TT>Unix.getpid<CODE> </CODE>()<TT>)</TT><CODE> </CODE>pid01<CODE> </CODE>pid0<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_generation1<CODE> </CODE>pid01<CODE> </CODE>pid0<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>match</B><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE> </CODE><B>let</B><CODE> </CODE>pid02<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Unix.getpid<CODE> </CODE>()<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><B>match</B><CODE> </CODE>Unix.fork()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_generation2<CODE> </CODE><TT>(</TT>Unix.getpid<CODE> </CODE>()<TT>)</TT><CODE> </CODE>pid02<CODE> </CODE>pid0<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_generation1<CODE> </CODE>pid02<CODE> </CODE>pid0<CODE> </CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"I am %d, father and grandfather\n"</CODE><CODE> </CODE>pid0<CODE> </CODE>;;<BR><BR>

</PRE>
<BR>
<BR>
We obtain:<BR>

<PRE>
<CODE>I am 10644, father and grandfather</CODE><BR><CODE>I am 10645, son of 10644</CODE><BR><CODE>I am 10648, son of 10645, grandson of 10644</CODE><BR><CODE>I am 10646, son of 10644</CODE><BR><CODE>I am 10651, son of 10646, grandson of 10644</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="toc249"></A>
<H3> Order and Moment of Execution</H3>
A sequence of process creations without synchronization may lead to
surprising effects. This is illustrated by the following poem writing
program � la M. Jourdain<A NAME="text43" HREF="book-ora172.html#note43"><SUP><FONT SIZE=2>4</FONT></SUP></A>:<BR>

<PRE>
<B>match</B><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"fair Marquise "</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<BR><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>match</B><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"your beautiful eyes "</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>match</B><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"make me die "</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"of love\n"</CODE><CODE> </CODE>;<CODE> </CODE><CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
It may produce the following result:<BR>

<PRE>
<CODE>of love</CODE><BR><CODE>fair Marquise your beautiful eyes make me die </CODE>

</PRE>
<BR>
<BR>
We usually want our program to be able to assure the order of
execution of its processes. More generally speaking, an application
which makes use of several processes may have to synchronize them.
Depending on the model of parallelism in use, the synchronization
is realized by communication between the processes or by waiting
conditions. This subject is presented more profoundly by the two
following chapters. For the moment, we can improve our poem writing
program in two ways:<BR>
<BR>
<UL>
<LI>
 Give the child the time to write its phrase before writing
the own.

<LI> Wait for the termination of the child, which will then have
written its phrase, before writing our own phrase.
</UL>
<H5> Delays.</H5>
<A NAME="@fonctions424"></A>
A process can suspend its activity by calling the function:


<PRE><BR># Unix.sleep<CODE> </CODE>;;<BR><CODE>- : int -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

The argument provides the number of seconds during which the process wants to
suspend its activities.<BR>
<BR>
Using this function, we write:<BR>

<PRE>
<B>match</B><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"fair Marquise "</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Unix.sleep<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE>"your beautiful eyes "</CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Unix.sleep<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE>"make me die "</CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Unix.sleep<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"of love\n"</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
And we can obtain:<BR>

<PRE>
<CODE>fair Marquise your beautiful eyes make me die of love</CODE><BR>

</PRE>
<BR>
<BR>
Nevertheless, this method is not sure. In theory, it would be
possible that the system gives enough time to one of the processes
to sleep and to write its output at the same turn. Therefore
we prefer the following method for assuring the execution order
of our processes.<BR>
<BR>
GGH<BR>
<BR>

<H5> Waiting for the termination of the child.</H5>
<A NAME="@fonctions425"></A>
A parent process may wait for his child to
terminate through a call to the function:


<PRE><BR># Unix.wait<CODE> </CODE>;;<BR><CODE>- : unit -&gt; int * Unix.process_status = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
The execution of the parent is suspended until one of its children
terminates. If <TT>wait</TT> is called by a process
not having any children, a <TT>Unix_error</TT> is thrown.
We will discuss later the return value of <TT>wait</TT>.
For the moment, we will just use the command to pronounce our poem:<BR>

<PRE>
<B>match</B><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"fair Marquise "</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>ignore<CODE> </CODE><TT>(</TT>Unix.wait<CODE> </CODE>()<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"your beautiful eyes "</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>ignore<CODE> </CODE><TT>(</TT>Unix.wait<CODE> </CODE>()<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>Unix.fork<CODE> </CODE>()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"make me die "</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>ignore<CODE> </CODE><TT>(</TT>Unix.wait<CODE> </CODE>()<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"of love\n"</CODE><CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE><BR>

</PRE>
<BR>
<BR>
Indeed, we obtain:<BR>

<PRE>
<CODE>fair Marquise your beautiful eyes make me die of love</CODE><BR>

</PRE>
<BR>
<BR>


<H3> Warning </H3> <HR>

<TT>fork</TT> is proprietary to the Unix system


<HR>

<BR>
<BR>
<A NAME="toc250"></A>
<H3> Descendence, Death and Funerals of Processes</H3>
The function <TT>wait</TT> is useful not only to wait for
the termination of a child. It also has the responsibility
to complete the death of the child process.<BR>
<BR>
Whenever a process is created, the system adds an entry in a table.
The table serves to keep track of all processes. When a process
terminates, the entry does not disappear automatically in the table.
It is the responsibility of the parent to assure the deletion
by the call of <TT>wait</TT>. If this is not done, the child process
keeps an entry in the table. This is called a
zombie process.<A NAME="@concepts341"></A><BR>
<BR>
When the system is started, a first process called <TT>init</TT> is
started. After the initialization of some parameters, the essential
role of this ``forefather'' is to take care of orphan processes
and to call the <TT>wait</TT> which deletes them from the process
table after their termination.<BR>
<BR>

<H4> Waiting for the Termination of a Given Process</H4>
There is a variation of the function <TT>wait</TT>, named <TT>waitpid</TT>.
This command is supported on Unix and Windows:
<A NAME="@fonctions426"></A>


<PRE><BR># Unix.waitpid<CODE> </CODE>;;<BR><CODE>- : Unix.wait_flag list -&gt; int -&gt; int * Unix.process_status = &lt;fun&gt;</CODE><BR>

</PRE>

The first argument specifies the waiting modalities. The second
indicates which process or which group of processes are treated.<BR>
<BR>
After the termination of a process, two pieces of information can be accessed
by its parent as a result of the function calls <TT>wait</TT> or
<TT>waitpid</TT>: the number of the terminated process and its exit status.
The status is represented by a value of type
<I>Unix.process_status</I>.
<A NAME="type-process-status"></A> 
<A NAME="@fonctions427"></A>
This type has three constructors. Each of them takes an integer
as argument.
<UL>
<LI>
 <EM>WEXITED n</EM>: the process has terminated normally
with the return code <EM>n</EM>.

<LI> <EM>WSIGNALED n</EM>: the process has been killed by the
signal <EM>n</EM>.

<LI> <EM>WSTOPPED n</EM>: the process has been stopped by the signal
 <EM>n</EM>.
</UL>
The last value only makes sense for the function <TT>waitpid</TT>
which can listen for such signals as indicated by its first argument.
We will discuss signals and their treatment at page
<A HREF="book-ora168.html#sec-signals">??</A>.<BR>
<BR>

<H4> Managing of Waiting by Ancestors</H4>
In order to avoid having to care for the termination of child processes oneself,
it is possible to delegate this responsibility to an ancestor process.
``Double fork'' allows a process not to take care of the funerals of all
its child processes, but to delegate this responsibility to the <TT>init</TT>
process. Here is the principle: a process <I>P</I><SUB><FONT SIZE=2>0</FONT></SUB> creates a process
<I>P</I><SUB><FONT SIZE=2>1</FONT></SUB>, which in turn creates a third process <I>P</I><SUB><FONT SIZE=2>2</FONT></SUB>. Then <I>P</I><SUB><FONT SIZE=2>1</FONT></SUB>
terminates. So <I>P</I><SUB><FONT SIZE=2>2</FONT></SUB> is orphan and will be adopted by <TT>init</TT>,
which waits for its termination. The initial process <I>P</I><SUB><FONT SIZE=2>0</FONT></SUB> can execute
a <TT>wait</TT> for <I>P</I><SUB><FONT SIZE=2>1</FONT></SUB> which will be of short duration. The idea is
to delegate to the grandchild the work which otherwise would have
been for the child.<BR>
<BR>
The schema is the following:


<PRE><BR># <B>match</B><CODE> </CODE>Unix.fork()<CODE> </CODE><B>with</B><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* P0 creates P1 *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>if</B><CODE> </CODE>Unix.fork()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>then</B><CODE> </CODE>exit<CODE> </CODE><CODE>0</CODE><CODE> </CODE>;<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* P1 creates P2 and terminates *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"P2 did its work\n"</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>exit<CODE> </CODE><CODE>0</CODE><CODE> </CODE><BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>pid<CODE> </CODE>-&gt;<CODE> </CODE>ignore<CODE> </CODE><TT>(</TT>Unix.waitpid<CODE> </CODE>[]<CODE> </CODE>pid<TT>)</TT><CODE> </CODE>;<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* P0 waits for P1 to terminate *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"P0 can do other things without waiting\n"</CODE><CODE> </CODE>;;<BR><CODE>P2 did its work</CODE><BR><CODE>P0 can do other things without waiting</CODE><BR><CODE>- : unit = ()</CODE><BR>

</PRE>

We will apply this principle to handle requests sent to a server
in chapter <A HREF="index.html#chap-PD">20</A>.<BR>
<BR>
<HR>
<A HREF="book-ora166.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora168.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
